package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.aliyun.GreenImageScan;
import com.heima.aliyun.GreenTextScan;
import com.heima.common.exception.CustException;
import com.heima.constants.message.PublishArticleConstants;
import com.heima.feigns.AdminFeign;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wmmedia.pojos.WmNews;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {
    @Autowired
    private WmNewsMapper wmNewsMapper;
    @Autowired
    private AdminFeign adminFeign;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Value("${file.oss.web-site}")  //"http://hmleadnewswxd.oss-cn-beijing.aliyuncs.com"  前缀访问路径
    String webSite;

    //自媒体文章审核
    @Override
    public void autoScanWmNews(Integer id) {
        //非空判断
        if (id == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //根据文章id查询文章
        WmNews wmNews = wmNewsMapper.selectById(id);
        //非空判断
        if (wmNews == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在!");
        }
        //文章存在,判断文章是否待审核状态
        if (!wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "当前文章未处于待审核状态!");
        }
        //文章存在,解析文章,获取内容和文本
        Map<String, Object> imagesContentMap = parseContent(wmNews);
        //判断文章的文本内容是否存在敏感词
        boolean sensitiveResult = handleSensitive((String) imagesContentMap.get("text"), wmNews);
        if (!sensitiveResult) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "文本存在敏感词,审核未通过!");
        }
        //使用阿里云内容检测审核文本
        boolean textResult = textHandle((String) imagesContentMap.get("text"), wmNews);
        if (!textResult) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "文本审核未通过!");
        }
        //使用阿里云内容检测审核图片
        boolean imagesResult = imageHandle((List<String>) imagesContentMap.get("images"), wmNews);
        if (!imagesResult) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "图片审核未通过!");
        }
        //审核通过
        updateWmNews(wmNews, WmNews.Status.SUCCESS.getCode(), "文章审核成功!");
        //判断是否到达发布时间
        //获取发送时间
        long publishTime = wmNews.getPublishTime().getTime();
        long nowTime = new Date().getTime();
        long delayTime = publishTime - nowTime;
        //判断发布时间,发送mq延时消息,发布文章
        rabbitTemplate.convertAndSend(PublishArticleConstants.DELAY_DIRECT_EXCHANGE
                , PublishArticleConstants.PUBLISH_ARTICLE_ROUTE_KEY
                , wmNews.getId(), new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) throws AmqpException {
                        message.getMessageProperties().setHeader("x-delay", delayTime < 0 ? 0 : delayTime);
                        return message;
                    }
                }
        );
    }

    //文章解析获取内容和文本
    public Map<String, Object> parseContent(WmNews wmNews) {
        //抽取文章内容
        String content = wmNews.getContent();
        //非空判断
        if (content == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "文章内容不存在!");
        }
        //使用JSON工具解析JSON类型文本
        List<Map> maps = JSON.parseArray(content, Map.class);
        //抽取文章中的文本内容
        String contentResult = maps.stream().filter(map -> {
            return map.get("type").equals("text");
        }).map(map -> {
            return (String) map.get("value");
        }).collect(Collectors.joining("_hmtt_"));

        //抽取文章中的图片链接
        List<String> contentImageUrlList = maps.stream().filter(map -> {
            return map.get("type").equals("image");
        }).map(map -> {
            return (String) map.get("value");
        }).collect(Collectors.toList());

        //抽取封面中的图片链接
        String imageCoverRawText = wmNews.getImages();
        //非空判断
        if (imageCoverRawText != null) {
            List<String> imageCoverUrlList = Arrays.stream(imageCoverRawText.split(",")).map(url -> {
                return url = webSite + url;
            }).collect(Collectors.toList());
            //添加到图片集合
            contentImageUrlList.addAll(imageCoverUrlList);
            //去重
            contentImageUrlList = contentImageUrlList.stream().distinct().collect(Collectors.toList());
        }
        //创建map集合,保存
        HashMap<String, Object> imagesContentMap = new HashMap<>();
        imagesContentMap.put("text", contentResult);
        imagesContentMap.put("images", contentImageUrlList);
        //返回给调用者
        return imagesContentMap;
    }

    //判断文章的文本内容是否存在敏感词
    public boolean handleSensitive(String contentText, WmNews wmNews) {
        boolean flag = true;
        //查询敏感词
        ResponseResult<List<String>> sensitivesResp = adminFeign.sensitives();
        //非空判断
        if (sensitivesResp.getCode() != 0) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "敏感词词典不存在");
        }
        //初始化敏感词字典
        SensitiveWordUtil.initMap(sensitivesResp.getData());
        //进行敏感词判断
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(contentText);
        //判断是否存在
        if (stringIntegerMap.size() > 0) {
            //有敏感词,文章审核不通过
            updateWmNews(wmNews, WmNews.Status.FAIL.getCode(), "文章包含敏感词,审核不通过!");
            flag = false;
        }
        return flag;
    }

    //修改文章方法
    public void updateWmNews(WmNews wmNews, short status, String reason) {
        //设置wmNews
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        //修改到数据库
        wmNewsMapper.updateById(wmNews);
    }

    //阿里云文本审核
    public boolean textHandle(String contentText, WmNews wmNews) {
        boolean flag = true;
        try {
            //校验
            Map map = greenTextScan.greenTextScan(contentText);
            if (map != null) {
                //判断
                String suggestion = (String) map.get("suggestion");
                if (suggestion.equals("review")) {
                    //文本中有不确定内容,转为人工审核
                    flag = false;
                    updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "文章中有不确定内容,转为人工审核");
                }
                if (suggestion.equals("block")) {
                    //文本中有违规内容,修改
                    flag = false;
                    updateWmNews(wmNews, WmNews.Status.FAIL.getCode(), "文章中有违规内容,请修改!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "阿里云内容服务异常，转为人工审核");
            flag = false;
        }
        return flag;
    }

    //阿里云图片审核
    public boolean imageHandle(List<String> imageList, WmNews wmNews) {
        boolean flag = true;
        try {
            //校验
            Map map = greenImageScan.imageUrlScan(imageList);
            if (map != null) {
                //判断
                String suggestion = (String) map.get("suggestion");
                if (suggestion.equals("block")) {
                    //图片中有违规内容,修改
                    flag = false;
                    updateWmNews(wmNews, WmNews.Status.FAIL.getCode(), "图片中有违规内容,请修改!");
                }
                if (suggestion.equals("review")) {
                    //图片中有不确定内容,转为人工审核
                    flag = false;
                    updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "图片中有不确定内容,转为人工审核");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            updateWmNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "阿里云内容服务异常，转为人工审核");
            flag = false;
        }
        return flag;
    }
}
